package org.dromara.visitor.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.visitor.domain.dto.RuleAddReq;
import org.dromara.visitor.domain.dto.RuleQueryReq;
import org.dromara.visitor.domain.dto.RuleResp;
import org.dromara.visitor.domain.entity.OrgManage;
import org.dromara.visitor.domain.entity.Rule;
import org.dromara.visitor.domain.entity.RuleOrg;
import org.dromara.visitor.mapper.OrgManageMapper;
import org.dromara.visitor.mapper.RuleMapper;
import org.dromara.visitor.mapper.RuleOrgMapper;
import org.dromara.visitor.service.RuleService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class RuleServiceImpl extends ServiceImpl<RuleMapper, Rule> implements RuleService {

    @Resource
    private RuleOrgMapper ruleOrgMapper;

    @Resource
    private RuleMapper ruleMapper;
    @Resource
    private OrgManageMapper orgManageMapper;
    @Override
    public void addRule(RuleAddReq req) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        Rule rule = new Rule();
        BeanUtils.copyProperties(req, rule);
        rule.setCreateBy(loginUser.getUserId());
        rule.setUpdateTime(LocalDateTime.now());
        rule.setUpdateBy(loginUser.getUserId());
        rule.setCreateTime(LocalDateTime.now());
        this.save(rule);
        //关联组织
        if(CollectionUtils.isNotEmpty(req.getRuleOrgList())){
            List<RuleOrg> ruleOrgList = req.getRuleOrgList();
            ruleOrgList.forEach(ruleOrg -> {
                ruleOrg.setRuleId(rule.getId());
                ruleOrg.setCreateBy(loginUser.getUserId());
                ruleOrg.setUpdateTime(LocalDateTime.now());
                ruleOrg.setUpdateBy(loginUser.getUserId());
                ruleOrg.setCreateTime(LocalDateTime.now());
            });
            ruleOrgMapper.insert(ruleOrgList);
        }
    }

    @Override
    public void editRule(RuleAddReq req) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        Rule rule = new Rule();
        BeanUtils.copyProperties(req, rule);
        rule.setUpdateTime(LocalDateTime.now());
        rule.setUpdateBy(loginUser.getUserId());
        this.updateById(rule);
        //先删除关联
        QueryWrapper<RuleOrg> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("rule_id",rule.getId());
        ruleOrgMapper.delete(queryWrapper);
        //关联组织
        if(CollectionUtils.isNotEmpty(req.getRuleOrgList())){
            List<RuleOrg> ruleOrgList = req.getRuleOrgList();
            ruleOrgList.forEach(ruleOrg -> {
                ruleOrg.setRuleId(rule.getId());
                ruleOrg.setCreateBy(loginUser.getUserId());
                ruleOrg.setUpdateTime(LocalDateTime.now());
                ruleOrg.setUpdateBy(loginUser.getUserId());
                ruleOrg.setCreateTime(LocalDateTime.now());
            });
            ruleOrgMapper.insert(ruleOrgList);
        }
    }

    @Override
    public RuleAddReq detail(Long id) {
        Rule rule = this.getById(id);
        RuleAddReq ruleAddReq = new RuleAddReq();
        BeanUtils.copyProperties(rule,ruleAddReq);
        //查询关联组织
        List<RuleOrg> ruleOrgList = ruleOrgMapper.listByRuleId(id);
        ruleAddReq.setRuleOrgList(ruleOrgList);
        return ruleAddReq;
    }

    @Override
    public Page<RuleResp> queryRuleList(RuleQueryReq req) {
        //查下组织表
        if(CollectionUtils.isNotEmpty(req.getOrgIds())){
            List<RuleOrg> ruleOrgList = ruleOrgMapper.selectByIds(req.getOrgIds());
            if(CollectionUtils.isNotEmpty(ruleOrgList)){
                List<Long> ruleIds = ruleOrgList.stream().map(RuleOrg::getRuleId).collect(Collectors.toList());
                req.setRuleIds(ruleIds);
            }
        }
        Page<RuleResp> page = new Page<>(req.getPageNum(),req.getPageSize());
        List<RuleResp> list = ruleMapper.queryRuleList(page,req);
        //关联组织与使用人数
        if(CollectionUtils.isNotEmpty(list)){
           List<Long> ruleIds = list.stream().map(RuleResp::getId).collect(Collectors.toList());
           List<RuleOrg> ruleOrgList = ruleMapper.queryRuleOrgList(ruleIds);
           if(CollectionUtils.isNotEmpty(ruleOrgList)){
               Map<Long, List<RuleOrg>> ruleOrgMap = ruleOrgList.stream().collect(Collectors.groupingBy(RuleOrg::getRuleId));
               //通过组织查人数
               List<Long> orgId = ruleOrgList.stream().map(RuleOrg::getOrgId).collect(Collectors.toList());
               LambdaQueryWrapper<OrgManage> orgManageLambdaQueryWrapper = new LambdaQueryWrapper<>();
               orgManageLambdaQueryWrapper.select(OrgManage::getId,OrgManage::getOrgId);
               orgManageLambdaQueryWrapper.in(OrgManage::getOrgId,orgId);
               List<OrgManage> orgManageList = orgManageMapper.selectList(orgManageLambdaQueryWrapper);
               Map<Long, Long> orgCountMap = orgManageList.stream().collect(Collectors.groupingBy(OrgManage::getOrgId, Collectors.counting()));
               for(RuleResp ruleResp : list){
                   List<RuleOrg> ruleOrgs = ruleOrgMap.get(ruleResp.getId());
                   String orgNames = "";
                   int orgCount = 0;
                   if(CollectionUtils.isNotEmpty(ruleOrgs)){
                       for(RuleOrg ruleOrg : ruleOrgs){
                           orgNames += ruleOrg.getOrgName() + "、";
                           if(orgCountMap.containsKey(ruleOrg.getOrgId())){
                               orgCount = orgCount + orgCountMap.get(ruleOrg.getOrgId()).intValue();
                           }
                       }
                   }
                   if(orgNames.length() > 0){
                       orgNames = orgNames.substring(0,orgNames.length()-1);
                   }
                   ruleResp.setTotalPersons(orgCount);
                   ruleResp.setOrgNames(orgNames);

               }
           }
        }
        page.setRecords(list);
        return page;
    }

    @Override
    public Rule getRuleByOrgId(Long orgId) {
        RuleOrg ruleOrg = ruleOrgMapper.selectOne(new QueryWrapper<RuleOrg>().eq("org_id",orgId));
        Rule rule = ruleMapper.selectById(ruleOrg.getRuleId());
        return rule;
    }
}
